#include "app_device.h"
 device_t *device = NULL;
 int app_device_send_task(void *arg)
 {
    //1.从缓冲区取数据
    char data[256];
    int data_len = app_buffer_read(device->up_buffer, data, 256);
    if (data_len <= 0)
    {
        log_error("app_buffer_read failed");
        return -1;
    }
    char *json_str = app_message_charsToJson(data,data_len);
    if (json_str == NULL)
    {
        log_error("app_message_charsToJson failed");
        return -1;
    }
    //2.发送数据到mqtt
    int ret = app_mqtt_send(json_str);
    if (ret != 0)
    {
        log_error("app_mqtt_send failed");
        return -1;
    }
    free(json_str);
    return 0;
    
 }
 /**
  * @brief 轮训执行的线程函数,用来轮训蓝牙文件是否有数据可读
  * 1.读取文件的新增内容
  * 2.将数据写入上行缓冲区
  * 3.调用线程池处理上行缓冲区的数据
  * @param arg 线程参数
  * @return void* 线程返回值
  */
 static void * app_device_read_thread_func(void *arg)
 {
    while (device->is_running)
    {
        char data[256];
        int data_len = read(device->fd, data, 256);
        if (data_len <= 0)
        {
            // log_error("read file %s failed", device->file_name);
            continue;
        }
        if (data_len > 0 && device->post_read)
        {
            data_len = device->post_read(data, data_len);
        }
        if (data_len >0)
        {
            int ret = app_buffer_write(device->up_buffer, data, data_len);
            if (ret == -1)
            {
                log_error("app_buffer_write failed");
                continue;
            }
            //调用线程池处理
            app_pool_register_task(app_device_send_task, NULL);
        }
        
        

    }
    return NULL;
    
 }
 /**
  * @brief 线程函数,用来将下行缓冲区的数据写入蓝牙文件
  */
 static int app_device_write_task(void *arg)
 {
    //1.从缓冲区取数据
    char data[256];
    int data_len = app_buffer_read(device->down_buffer, data, 256);
    if (data_len <= 0)
    {
        log_error("app_buffer_read failed");
        return -1;
    }
    //2.两次写入时间要大于200ms
    long long time_diff = app_common_getCurrentTime() - device->last_write_time;
    if(time_diff < 200)
    {
        usleep((200 - time_diff) * 1000);
    }
    //3.将数据写入蓝牙文件
    int ret = write(device->fd, data, data_len);
    if (ret != data_len)
    {
        log_error("写入蓝牙文件失败");
        return -1;
    }
    //4.修改上一次写入的时间
    device->last_write_time = app_common_getCurrentTime();
    log_info("将数据写入蓝牙成功%.*s", data_len,data);
    return 0;
 }
static int app_mqtt_recv_callback(char * json_str)
{
    char chars_buffer[256];
    int chars_len = app_message_jsonToChars(json_str,chars_buffer,256);
    if (chars_len <= 0)
    {
       log_error("接收到的数据解析失败");
       return -1;
    }
    // 判断是否需要进行写缓冲区前预处理
    if (device->pre_write)
    {
        chars_len = device->pre_write(chars_buffer, chars_len);
        if(chars_len <= 0)
        {
            log_error("解析成蓝牙数据格式失败");
            return -1;
        }
    }
    //将数据写入下行缓冲区
    int ret = app_buffer_write(device->down_buffer, chars_buffer, chars_len);
    if (ret ==-1)
    {
        log_error("写入下行区缓冲失败");
        return -1;
    }
    // 将下发数据(将数据写入蓝牙文件)操作交给线程池
    app_pool_register_task(app_device_write_task, NULL);
    return 1;
    
}
device_t * app_device_init(char * file_name)
{
    //初始化设备结构体
    device = (device_t *)malloc(sizeof(device_t));
    if (device == NULL)
    {
        return NULL;
    }
    memset(device, 0, sizeof(device_t));
    device->file_name = file_name;
    device->fd = open(file_name, O_RDWR|O_APPEND);
    if (device->fd < 0)
    {
        log_error("open file %s failed", file_name);
        free(device);
        return NULL;
    }
    device->up_buffer = app_buffer_init(1024);
    device->down_buffer = app_buffer_init(1024);
    if (device->up_buffer == NULL || device->down_buffer == NULL)
    {
        log_error("app_buffer_init failed");
        free(device);
        return NULL;
    }

    device->read_thread =0;
    device->is_running = 0;
    device->last_write_time = 0;
    device->post_read = NULL;
    device->pre_write = NULL;

    //初始化mqtt 线程 
    app_pool_init(5);
    app_mqtt_init();
    app_mqtt_register_recv_callback(app_mqtt_recv_callback);
   
    
    return device;


}
int app_device_start(void)
{
    if(device->is_running == 1)
    {
        log_info("设备已经启动");
        return 0;
    }
    device->is_running = 1;

    //创建读线程
    int ret = pthread_create(&device->read_thread, NULL, app_device_read_thread_func, NULL);
    if (ret != 0)
    {
        log_error("pthread_create failed");
        return -1;
    }
    return 0;
}
void app_device_destroy(void)
{
    app_buffer_free(device->up_buffer);
    app_buffer_free(device->down_buffer);
    pthread_cancel(device->read_thread);

    app_mqtt_close();
    app_pool_close();
    free(device);
    device = NULL;
}